package com.tg.app.activity.device.add;

import static com.inuker.bluetooth.library.Constants.REQUEST_SUCCESS;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.appbase.custom.config.ApiUrl;
import com.appbase.custom.constant.CommonConstants;
import com.base.BaseActivity;
import com.inuker.bluetooth.library.ClientManager;
import com.inuker.bluetooth.library.connect.options.BleConnectOptions;
import com.inuker.bluetooth.library.connect.response.BleWriteResponse;
import com.inuker.bluetooth.library.model.BleGattCharacter;
import com.inuker.bluetooth.library.model.BleGattService;
import com.inuker.bluetooth.library.search.SearchResult;
import com.tange.base.toolkit.PreferenceUtil;
import com.tange.base.toolkit.StringUtils;
import com.tange.module.add.match.DeviceMatchQuery;
import com.tange.module.add.wifi.DeviceWiFiConfiguration;
import com.tange.module.core.wifi.scan.BizWiFiUtil;
import com.tange.module.core.wifi.scan.WiFiScanManager;
import com.tange.module.core.wifi.scan.WifiToolkit;
import com.tange.module.socket.SocketIoConstants;
import com.tg.app.R;
import com.tg.app.bean.WifiItem;
import com.tg.app.bean.WifiItem_;
import com.tg.app.camera.AVIOCTRLDEFs;
import com.tg.app.helper.ActivityHelper;
import com.tg.app.report.DeviceAddReport;
import com.tg.app.report.DeviceAddReportBean;
import com.tg.app.util.LogUtils;
import com.tg.app.util.ObjectBoxUtil;
import com.tg.app.view.CustomCircleProgressBar;
import com.tg.appcommon.android.DeviceAddSoundConstants;
import com.tg.appcommon.android.DialogUtil;
import com.tg.appcommon.android.SoundPlayerManager;
import com.tg.appcommon.android.TGLog;
import com.tg.appcommon.android.TGToast;
import com.tg.data.helper.DeviceTypeHelper;
import com.tg.data.http.entity.DeviceMatchBean;

import java.util.List;
import java.util.UUID;

import io.objectbox.Box;

public class ApConnectActivityEx extends BaseActivity {
    public static final String TAG = "ApConnectActivityEx";
    private String bindToken;
    private String bleBindToken;
    private String mFrom = "wifi";
    public final static String EXT_BIND_TOKEN = "bind_token";
    public final static String EXT_FROM_CONNECT = "ext_from_connect";
    public final static String EXT_PLAY_SOUND = "EXT_PLAY_SOUND";
    public final static String EXT_BIND_START_TIME = "ext_bind_statr_times";
    private boolean isAddSuccess = false;
    private final static int EVENT_ADD = 0;
    public final static int EVENT_SET_NAME = 1;
    public final static int EVENT_ADD_MAX = 30;
    private int count = 0;
    private long deviceID;
    private TextView progress;
    private CustomCircleProgressBar circleProgressBar;
    private AddDeviceBroadCastReceiver receiver;
    private boolean isErr = false;
    private boolean isRunning = false;
    private String mUUID;
    private long mStartTime;
    private final boolean switchNetwork = false;
    private SearchResult searchResult;
    private UUID writeCharacters = null;
    private UUID writeService = null;
    private boolean playSound = true;

    private SoundPlayerManager soundPlayerManager;

    private final Handler uiHandler = new Handler(Looper.getMainLooper());
    private String deviceType = DeviceTypeHelper.DEVICE_WIFI;
    @SuppressLint("HandlerLeak")
    private final Handler handler = new Handler() {
        @SuppressLint("DefaultLocale")
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == EVENT_ADD) {
                TGLog.d(SelectBluetoothDeviceActivity.TAG, "isAddSuccess = " + isAddSuccess);
                if (!isAddSuccess) {
                    if (count % 5 == 0) {
                        matching();
                    }
                    int MAXCOUNT = 150;
                    if (count >= MAXCOUNT) {
                        connectError();
                        isErr = true;
                        return;
                    }
                    count++;
                    findViewById(R.id.rl_connect_tip).setVisibility(count >= EVENT_ADD_MAX? View.VISIBLE : View.GONE);
                    progress.setText(String.format("%d", MAXCOUNT - count));
                    circleProgressBar.setProgress(count);
                    handler.sendEmptyMessageDelayed(EVENT_ADD, 1000);
                }
            } else if (msg.what == EVENT_SET_NAME) {
                setDeviceName();
            }
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        TGLog.i(TAG,"onResume");
        isRunning = true;
        if (isErr) {
            connectError();
        } else if (isAddSuccess) {
            setDeviceName();
        }

        playSound();
    }

    private void playSound() {
        if (!playSound) return;
        if (soundPlayerManager != null) {
            soundPlayerManager.destroy();
        }
        soundPlayerManager = SoundPlayerManager.create(this);
        uiHandler.postDelayed(() -> {
            if (soundPlayerManager != null) {
                soundPlayerManager.download(DeviceAddSoundConstants.WifiConnect(ApConnectActivityEx.this), true);
            }
        }, 1000);
    }

    @Override
    protected void onPause() {
        super.onPause();
        isRunning = false;
        TGLog.i(TAG,"onPause");
        pauseSound();
    }

    private void pauseSound() {
        if (!playSound) return;
        uiHandler.removeCallbacksAndMessages(null);
        if (soundPlayerManager != null) {
            soundPlayerManager.destroy();
        }
    }

    @Override
    public boolean shouldSetStatusBarColor() {
        return true;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        requestWindowFeature(Window.FEATURE_NO_TITLE);//remove title bar  即隐藏标题栏
        setContentView(R.layout.fragment_ap_connect_new);
        hideActionBar();
        initView();
        receiver = new AddDeviceBroadCastReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(SocketIoConstants.NOTIFY_ADD_DEVICE);
        registerReceiver(receiver, filter);
        playSound = getIntent().getBooleanExtra(ApConnectActivityEx.EXT_PLAY_SOUND, true);
        mFrom = getIntent().getStringExtra(EXT_FROM_CONNECT);
        bindToken = getIntent().getStringExtra(EXT_BIND_TOKEN);
        mStartTime = getIntent().getLongExtra(EXT_BIND_START_TIME, System.currentTimeMillis());
        mUUID = getIntent().getStringExtra(ApSetWifiActivityEx.EXT_WIFI_UUID);
        handler.sendEmptyMessageDelayed(EVENT_ADD, 1000);
        TGLog.i(SelectBluetoothDeviceActivity.TAG,"mUUID:"+mUUID);
        if (StringUtils.equalsIgnoreCase("wifi", mFrom)){
            DeviceAddReportBean bean = DeviceAddReport.getInstance().getReportBean();
            if (bean != null) {
                bean.connectLoadStart = System.currentTimeMillis();
                DeviceAddReport.getInstance().setReportBean(bean);
            }
            LogUtils.trackCustomBeginKVEvent(getBaseContext(), "bind_ap_new", "matching");
            String wifi = WifiToolkit.getCurWifi();
            TGLog.d(TAG + "wifi ====  " + wifi);
            WiFiScanManager.scanner().resetDeviceNetWork(this);
            WifiManager mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
            if (mWifiManager.isWifiEnabled()) {
                mWifiManager.startScan();
            }
        }else if (StringUtils.equalsIgnoreCase(ApSetWifiActivityEx.EXT_DEVICE_BLUETOOTH, mFrom)){
            connectWifi();

        }
    }

    @Override
    protected void initView() {
        circleProgressBar = findViewById(R.id.loading_progress);
        progress = findViewById(R.id.tv_progress);
        findViewById(R.id.back_toolbar).setOnClickListener(view -> btnBackClick());

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
        handler.removeCallbacksAndMessages(null);
    }

    @Override
    public void onBackPressed() {
        btnBackClick();
    }


    private void matching() {
        TGLog.d(SelectBluetoothDeviceActivity.TAG,"ApConnectActivityEx matching" + bindToken + ", isAddSuccess = " + isAddSuccess);
        if (!isAddSuccess && !StringUtils.isEmpty(bindToken)) {

            DeviceMatchQuery.create().request(bindToken, new DeviceMatchQuery.Callback() {
                @Override
                public void onSuccess(DeviceMatchBean deviceMatchBean) {
                    if (!isAddSuccess) {
                        if (!TextUtils.isEmpty(deviceMatchBean.getDevice_type())){
                            deviceType = deviceMatchBean.getDevice_type();
                        }

                        deviceID = deviceMatchBean.getId();
                        mUUID = deviceMatchBean.getUuid();
                        TGLog.i(SelectBluetoothDeviceActivity.TAG,"DeviceMatchQuery  uuid:"+mUUID);
                        handler.removeMessages(EVENT_SET_NAME);
                        handler.sendEmptyMessage(EVENT_SET_NAME);
                        isAddSuccess = true;
                        if (deviceMatchBean.getIs_online() == 0) {
                            Toast.makeText(getBaseContext(), R.string.device_app_succeed_wait_online, Toast.LENGTH_LONG).show();
                        }
                    }
                }

                @Override
                public void onError(int errorCode, String errorMsg) {
                    TGLog.i(SelectBluetoothDeviceActivity.TAG, "[onError] errorCode = " + errorCode + ", errorMsg = " + errorMsg);
                }
            });
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void checkNetworkError() {
        String name = getIntent().getStringExtra(ApSetWifiActivityEx.EXT_WIFI_NETWORD);
        String pwd = getIntent().getStringExtra(ApSetWifiActivityEx.EXT_WIFI_PWD);
        TGLog.d(TAG + "checkNetworkError name " + name + "pwd = " + pwd);
        BizWiFiUtil.removeDeviceWifi();
  //      WifiUtil.addNetworkWifi(curWifi, name, pwd);
    }

    private void setDeviceName() {
        if (isRunning) {
            setAddEndReport();
            String name = getIntent().getStringExtra(ApSetWifiActivityEx.EXT_WIFI_NETWORD);
            String pwd = getIntent().getStringExtra(ApSetWifiActivityEx.EXT_WIFI_PWD);
            WifiItem item = new WifiItem(name, pwd);
            TGLog.d("name = " + name + ",pwd = " + pwd);
            if (!StringUtils.isEmpty(name) && !StringUtils.isEmpty(pwd)) {
                Box<WifiItem> box = ObjectBoxUtil.getWifiItem();
                if (box != null) {
                    WifiItem wifiItem = box.query().equal(WifiItem_.uuid, name).build().findFirst();
                    if (wifiItem == null) {
                        TGLog.d("item.name = " + item.uuid + ",pwd = " + item.password);
                        box.put(item);
                    } else {
                        wifiItem.password = pwd;
                        TGLog.d("wifiItem.name = " + wifiItem.uuid + ",pwd = " + wifiItem.password);
                        box.put(wifiItem);
                    }
                }
            }
            AddDeviceReportHelper.onEventLongTimeByName(TAG, "bind_device", System.currentTimeMillis() - mStartTime);
            BizWiFiUtil.removeDeviceWifi();
            Intent intent = new Intent(getBaseContext(), ApSetNameActivity.class);
            intent.putExtra(ApiUrl.DEVICEID, deviceID);
            intent.putExtra(ApiUrl.DEVICE_UUID, mUUID);
            intent.putExtra(ApiUrl.DEVICE_TYPE, deviceType);
            startActivity(intent);
            finish();
        }
    }

    private void removeDialogView(){
        View view = getWindow().getDecorView();
        if (view.findViewById(R.id.tv_device_ap_add_title)==null){
         super.onBackPressed();
            TGToast.showToast("dialog toast!!!!");
        }
    }

    private void btnBackClick() {
        AddDeviceReportHelper.onEventClickByName(TAG, "back_toolbar");
        DialogUtil.openDlalog(this,
                R.string.notice_4g_car,
                R.string.confirm_to_add_4g_car,
                R.string.confirm,
                R.string.cancle_add_4g_car,
                v -> {
                    AddDeviceReportHelper.onEventClickByName(TAG, "dialog_confirm_btn");
                    BizWiFiUtil.removeDeviceWifi();
                    ActivityHelper.gotoDeviceListPage(ApConnectActivityEx.this);
                    finish();
                },
                v -> {
                    TGLog.d("v id =" + v.getId());
                    AddDeviceReportHelper.onEventClickByName(TAG, "dialog_cancel_btn");
                });
    }

    private void setAddEndReport() {
        DeviceAddReportBean bean = DeviceAddReport.getInstance().getReportBean();
        if (bean != null) {
            bean.connectLoadEnd = System.currentTimeMillis();
            bean.uuid = mUUID;
            DeviceAddReport.getInstance().setReportBean(bean);
        }
    }

    private void connectError() {
        if (isRunning) {
            setAddEndReport();
            ActivityHelper.gotoAddFailedActivity(this, null, mUUID, false, StringUtils.equalsIgnoreCase(mFrom, ApSetWifiActivityEx.EXT_DEVICE_BLUETOOTH));
            finish();
        }
    }


    private void connectWifi() {
        searchResult = getIntent().getParcelableExtra(ApSetWifiActivityEx.EXT_DEVICE_BLUETOOTH);
        BleConnectOptions options = new BleConnectOptions.Builder()
                .setConnectRetry(3)
                .setConnectTimeout(20000)
                .setServiceDiscoverRetry(3)
                .setServiceDiscoverTimeout(10000)
                .build();

        ClientManager.getClient().connect(searchResult.getAddress(), options, (code, profile) -> {
            TGLog.d(SelectBluetoothDeviceActivity.TAG, "profile= " + String.format("profile:\n%s", profile) + ", code = " + code);

            if (code == REQUEST_SUCCESS){
                List<BleGattService> bleGattServices = profile.getServices();
                if (bleGattServices == null) return;
                ClientManager.getClient().requestMtu(searchResult.getAddress(), 256, (code1, data) -> {

                });

                writeCharacters = null;
                writeService = null;
                for (BleGattService bleGattService : bleGattServices) {
                    List<BleGattCharacter> bleGattCharacters = bleGattService.getCharacters();
                    for (BleGattCharacter character : bleGattCharacters) {
                        int charaProp = character.getProperty();
                        if ((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0 && !((charaProp & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0)) {
                            writeCharacters = character.getUuid();
                            writeService = bleGattService.getUUID();
                            TGLog.d(TAG, "writeCharacters = " + writeCharacters + ", writeService = " + writeService);
                            break;
                        }
                        TGLog.d(TAG, "writeCharacters = " + writeCharacters + ", writeService = " + writeService);
                    }
                    if (writeService != null && writeCharacters != null){
                        break;
                    }
                }

                connectWifiImpl();
            }
        });
    }

    private final BleWriteResponse mWriteRsp = new BleWriteResponse() {
        @Override
        public void onResponse(int code) {
            TGLog.d(SelectBluetoothDeviceActivity.TAG, "code === " + code);
            if (code == REQUEST_SUCCESS) {
                bindToken = bleBindToken;
                matching();
            }
        }
    };

    private void connectWifiImpl() {
        TGLog.d(SelectBluetoothDeviceActivity.TAG,"connectWifi");
        String name = getIntent().getStringExtra(ApSetWifiActivityEx.EXT_WIFI_NETWORD);
        String pwd = getIntent().getStringExtra(ApSetWifiActivityEx.EXT_WIFI_PWD);
        TGLog.d(SelectBluetoothDeviceActivity.TAG, "name = " + name + ", pwd = " + pwd);
        if (!StringUtils.isEmpty(name) && !StringUtils.isEmpty(pwd)) {
            int userId = PreferenceUtil.getInt(this, CommonConstants.PRE_USER_ID);
            bleBindToken = DeviceWiFiConfiguration.createBindToken();
            TGLog.i(SelectBluetoothDeviceActivity.TAG, "Cs2Camera IOTYPE_USEREX_IPCAM_APLINK_SETWIFI_REQ");
            mStartTime = System.currentTimeMillis();
            if (writeService != null && writeCharacters != null){
                ClientManager.getClient().write(searchResult.getAddress(), writeService, writeCharacters, AVIOCTRLDEFs.EcpQrcodeContent.parseContent(name, pwd, userId, bleBindToken), mWriteRsp);
            }
        }
    }




    private class AddDeviceBroadCastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            assert action != null;
            if (action.equals(SocketIoConstants.NOTIFY_ADD_DEVICE)) {
                deviceID = intent.getLongExtra(CommonConstants.EXT_DEVICE_ID, 0);
                if (deviceID > 0 && !isErr) {
                    if (!isAddSuccess) {
                        handler.removeMessages(EVENT_SET_NAME);
                        handler.sendEmptyMessage(EVENT_SET_NAME);
                        isAddSuccess = true;
                    }

                }
            }
        }
    }

}
